package com.iplant.basic.serviceImpl.dao.bms;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.basicenum.bms.BMSWorkMode;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.bms.BMSTeam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BMSTeamDAO extends BaseDAO {
	private static BMSTeamDAO Instance = null;

	private BMSTeamDAO() {
		super();
	}

	private static Logger logger = LoggerFactory.getLogger(BMSTeamDAO.class);

	public static BMSTeamDAO getInstance() {
		if (Instance == null)
			Instance = new BMSTeamDAO();
		return Instance;
	}

	private BMSTeam BMS_CheckBMSTeam(BMSEmployee wLoginUser, BMSTeam wBMSTeam, OutResult<Integer> wErrorCode) {
		BMSTeam wResult = new BMSTeam();
		try {

			if (wBMSTeam == null || StringUtils.isEmpty(wBMSTeam.Name)) {
				wErrorCode.set(ExceptionTypes.Parameter.getValue());
				return wResult;
			}

			wErrorCode.set(0);
			String wInstance = super.getDBName();
			if (wErrorCode.Result != 0)
				return wResult;

			String wSQLText = StringUtils
					.Format("SELECT t1.ID FROM {0}.bms_team  t1 " + " where t1.ID!=:ID AND t1.FactoryID =:FactoryID"
							+ "  and t1.WorkshopID =:WorkshopID  and t1.WorkTypeID=:WorkTypeID"
							+ "  and ( t1.Name =:Name or t1.Code= :Code);", wInstance);

			wSQLText = this.DMLChange(wSQLText);
			Map<String, Object> wParams = new HashMap<String, Object>();
			wParams.put("ID", wBMSTeam.ID);
			wParams.put("FactoryID", wBMSTeam.FactoryID);
			wParams.put("WorkshopID", wBMSTeam.WorkshopID);
			wParams.put("WorkTypeID", wBMSTeam.WorkTypeID);
			wParams.put("Name", wBMSTeam.Name);
			wParams.put("Code", wBMSTeam.Code);

			List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParams);
			for (Map<String, Object> wSqlDataReader : wQueryResultList) {
				wResult.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));

			}
		} catch (Exception e) {
			logger.error("BMS_CheckBMSTeam", e);
			wErrorCode.set(ExceptionTypes.DBSQL.getValue());
		}
		return wResult;
	}

	private List<BMSTeam> BMS_GetTeamList(BMSEmployee wLoginUser, List<Integer> wIDList, String wCode, String wName,
			int wFactoryID, int wWorkshopID, int wDepartmentID, int wWorkTypeID, int wLeaderID, int wActive,
			Pagination wPagination, OutResult<Integer> wErrorCode) {
		List<BMSTeam> wResult = new ArrayList<BMSTeam>();
		try {
			if (wIDList == null)
				wIDList = new ArrayList<Integer>();

			wErrorCode.set(0);
			String wInstance = super.getDBName();
			if (wErrorCode.Result != 0)
				return wResult;

			String wSQLText = StringUtils.Format(
					"SELECT t1.*, t2.Name as DepartmentName,t2.Code as DepartmentCode,t6.Name as FactoryName,"
							+ " t5.Name as WorkTypeName,t5.WorkMode,  ifnull(t3.Name,t31.Name) as WorkshopName ,"
							+ " group_concat(distinct case when t4.ID = t1.CreatorID then  t4.Name else null end) as CreatorName,"
							+ " group_concat(distinct case when t4.ID = t1.EditorID then  t4.Name else null end) as EditorName,"
							+ " group_concat(distinct  case when FIND_IN_SET(t4.ID, t1.LeaderID) then  t4.Name else null end ) as LeaderName, "
							+ " group_concat(distinct  case when FIND_IN_SET(t4.ID, t1.LeaderID) then  t4.LoginID else null end ) as LeaderCode, "
							+ " group_concat(distinct  case when FIND_IN_SET(t4.ID, t1.MateID) then  t4.Name else null end ) as MateName, "
							+ " group_concat(distinct  case when FIND_IN_SET(t4.ID, t1.MateID) then  t4.LoginID else null end ) as MateCode "
							+ " FROM {0}.bms_team  t1 inner join  mbs_user as  t4 "
							+ " left join {0}.bms_department  t2  on  t1.DepartmentID=t2.ID "
							+ " left join {0}.bms_worktype  t5  on  t1.WorkTypeID=t5.ID "
							+ " left join {0}.fmc_factory  t6  on  t1.FactoryID=t6.ID "
							+ " left join {0}.fmc_workshop  t3  on  t5.WorkMode=:WorkShopMode and  t1.WorkshopID=t3.ID  "
							+ " left join {0}.wms_store  t31  on  t5.WorkMode=:WorkStoreMode and t1.WorkshopID=t31.ID   where 1=1 "
							+ " and ( :ID ='''' or t1.ID IN( {1} ) ) "
							+ " and ( :FactoryID<= 0 or t1.FactoryID =:FactoryID)  "
							+ " and ( :WorkshopID<= 0 or t1.WorkshopID =:WorkshopID)  "
							+ " and ( :Code = ''''  or t1.Code =:Code)  "
							+ " and ( :Name = ''''  or t1.Name like :Name)  "
							+ " and ( :LeaderID<= 0 or FIND_IN_SET( :LeaderID,t1.LeaderID))  "
							+ " and ( :WorkTypeID<= 0 or t1.WorkTypeID =:WorkTypeID)  "
							+ " and ( :DepartmentID<= 0 or t1.DepartmentID =:DepartmentID)  "
							+ " and ( :Active< 0 or t1.Active =:Active) group by t1.ID  ",
					wInstance, wIDList.size() > 0 ? StringUtils.Join(",", wIDList) : "0");

			wSQLText = this.DMLChange(wSQLText);
			Map<String, Object> wParams = new HashMap<String, Object>();
			wParams.put("ID", StringUtils.Join(",", wIDList));
			wParams.put("FactoryID", wFactoryID);
			wParams.put("WorkshopID", wWorkshopID);
			wParams.put("DepartmentID", wDepartmentID);
			wParams.put("Code", wCode);
			wParams.put("Name", StringUtils.isEmpty(wName) ? wName : "%" + wName + "%");
			wParams.put("LeaderID", wLeaderID);
			wParams.put("WorkTypeID", wWorkTypeID);
			wParams.put("WorkShopMode", BMSWorkMode.WorkShop.getValue());
			wParams.put("WorkStoreMode", BMSWorkMode.Store.getValue());
			wParams.put("Active", wActive);

			List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParams, wPagination);

			if (wQueryResultList.size() <= 0) {
				return wResult;
			}

			for (Map<String, Object> wSqlDataReader : wQueryResultList) {
				BMSTeam wDepartment = new BMSTeam();
				wDepartment.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
				wDepartment.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
				wDepartment.Name = StringUtils.parseString(wSqlDataReader.get("Name"));
				wDepartment.Description = StringUtils.parseString(wSqlDataReader.get("Description"));
				wDepartment.WorkMode = StringUtils.parseInt(wSqlDataReader.get("WorkMode"));
				wDepartment.WorkTypeID = StringUtils.parseInt(wSqlDataReader.get("WorkTypeID"));
				wDepartment.WorkTypeName = StringUtils.parseString(wSqlDataReader.get("WorkTypeName"));
				wDepartment.WorkshopID = StringUtils.parseInt(wSqlDataReader.get("WorkshopID"));
				wDepartment.WorkshopName = StringUtils.parseString(wSqlDataReader.get("WorkshopName"));
				wDepartment.FactoryID = StringUtils.parseInt(wSqlDataReader.get("FactoryID"));
				wDepartment.FactoryName = StringUtils.parseString(wSqlDataReader.get("FactoryName"));
				wDepartment.DepartmentID = StringUtils.parseInt(wSqlDataReader.get("DepartmentID"));
				wDepartment.DepartmentName = StringUtils.parseString(wSqlDataReader.get("DepartmentName"));
				wDepartment.DepartmentCode = StringUtils.parseString(wSqlDataReader.get("DepartmentCode"));
				wDepartment.CreatorID = StringUtils.parseInt(wSqlDataReader.get("CreatorID"));
				wDepartment.CreateTime = StringUtils.parseCalendar(wSqlDataReader.get("CreateTime"));
				wDepartment.EditorID = StringUtils.parseInt(wSqlDataReader.get("EditorID"));
				wDepartment.EditTime = StringUtils.parseCalendar(wSqlDataReader.get("EditTime"));
				wDepartment.Active = StringUtils.parseInt(wSqlDataReader.get("Active"));
				wDepartment.LeaderID = StringUtils
						.parseIntList(StringUtils.split(StringUtils.parseString(wSqlDataReader.get("LeaderID")), ","));

				wDepartment.LeaderName = StringUtils.parseString(wSqlDataReader.get("LeaderName"));
				wDepartment.LeaderCode = StringUtils.parseString(wSqlDataReader.get("LeaderCode"));

				wDepartment.MateID = StringUtils
						.parseIntList(StringUtils.split(StringUtils.parseString(wSqlDataReader.get("MateID")), ","));

				wDepartment.MateName = StringUtils.parseString(wSqlDataReader.get("MateName"));
				wDepartment.MateCode = StringUtils.parseString(wSqlDataReader.get("MateCode"));

				wDepartment.EditorName = StringUtils.parseString(wSqlDataReader.get("EditorName"));
				wDepartment.CreatorName = StringUtils.parseString(wSqlDataReader.get("CreatorName"));

				wResult.add(wDepartment);
			}
		} catch (Exception e) {
			logger.error("BMS_GetTeamList", e);
			wErrorCode.set(ExceptionTypes.DBSQL.getValue());
		}
		return wResult;
	}

	public List<BMSTeam> BMS_GetTeamList(BMSEmployee wLoginUser, String wName, int wFactoryID, int wWorkshopID,
			int wDepartmentID, int wWorkTypeID, int wLeaderID, int wActive, Pagination wPagination,
			OutResult<Integer> wErrorCode) {
		List<BMSTeam> wResult = new ArrayList<BMSTeam>();
		try {
			wErrorCode.set(0);

			wResult = BMS_GetTeamList(wLoginUser, null, "", wName, wFactoryID, wWorkshopID, wDepartmentID, wWorkTypeID,
					wLeaderID, wActive, wPagination, wErrorCode);
		} catch (Exception e) {
			logger.error("BMS_GetTeamList", e);
			wErrorCode.set(ExceptionTypes.DBSQL.getValue());
		}
		return wResult;
	}

	public List<BMSTeam> BMS_GetTeamList(BMSEmployee wLoginUser, List<Integer> wIDList, OutResult<Integer> wErrorCode) {
		List<BMSTeam> wResult = new ArrayList<BMSTeam>();
		try {
			wErrorCode.set(0);

			wResult = BMS_GetTeamList(wLoginUser, wIDList, "", "", 0, 0, 0, 0, 0, -1, Pagination.getMaxSize(),
					wErrorCode);
		} catch (Exception e) {
			logger.error("BMS_GetTeamList", e);
			wErrorCode.set(ExceptionTypes.Exception.getValue());
		}
		return wResult;
	}

	public BMSTeam BMS_GetTeam(BMSEmployee wLoginUser, int wID, String wCode, OutResult<Integer> wErrorCode) {
		BMSTeam wResult = new BMSTeam();
		try {
			wErrorCode.set(0);
			List<BMSTeam> wList = null;
			if (wID > 0) {
				wList = this.BMS_GetTeamList(wLoginUser, StringUtils.parseList(new Integer[] { wID }), "", "", 0, 0, 0,
						0, 0, -1, Pagination.getDefault(), wErrorCode);

			} else if (StringUtils.isNotEmpty(wCode)) {
				wList = this.BMS_GetTeamList(wLoginUser, null, wCode, "", 0, 0, 0, 0, 0, -1, Pagination.getDefault(),
						wErrorCode);
			}
			if (wList != null && wList.size() > 0) {
				wResult = wList.get(0);
				// wResult.TeamChargeList =
				// BMSTeamChargeDAO.getInstance().BMS_GetTeamChargeList(wLoginUser,
				// wResult.ID, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, wErrorCode);
			}
		} catch (Exception e) {
			logger.error("BMS_GetTeam", e);
			wErrorCode.set(ExceptionTypes.Exception.getValue());
		}
		return wResult;
	}

	public void BMS_UpdateTeam(BMSEmployee wLoginUser, BMSTeam wBMSTeam, OutResult<Integer> wErrorCode) {
		try {
			wErrorCode.set(0);
			String wInstance = super.getDBName();
			if (wErrorCode.Result != 0)
				return;

			BMSTeam wCheckTeam = this.BMS_CheckBMSTeam(wLoginUser, wBMSTeam, wErrorCode);
			if (wErrorCode.Result != 0)
				return;

			if (wCheckTeam != null && wCheckTeam.ID > 0) {
				wErrorCode.set(ExceptionTypes.Logic.getValue());
				return;
			}

			String wSQL = "";

			if (wBMSTeam.ID <= 0) {

				int wCount = super.GetMaxPrimaryKey(StringUtils.Format("{0}.bms_team", wInstance), "ID");

				wBMSTeam.Code = StringUtils.Format("BZ{0}", String.format("%07d", wCount + 1));

				wSQL = StringUtils.Format("INSERT INTO {0}.bms_team ( Code,LeaderID, "
						+ "Name, WorkTypeID,FactoryID, WorkshopID,DepartmentID,CreatorID, CreateTime, EditorID, "
						+ "EditTime, Active,MateID,Description) "
						+ "VALUES (:Code,:LeaderID,:Name, :WorkTypeID,:FactoryID,:WorkshopID,:DepartmentID,:CreatorID, "
						+ "now(), :EditorID, now(), :Active,:MateID,:Description);", wInstance);
			} else {

				BMSTeam wTeamTemp = this.BMS_GetTeam(wLoginUser, wBMSTeam.ID, "", wErrorCode);
				if (wTeamTemp == null || wTeamTemp.ID <= 0) {
					wErrorCode.set(ExceptionTypes.NotFound.getValue());
					return;
				}

				wSQL = StringUtils
						.Format("UPDATE {0}.bms_team SET  Name = :Name,Code = :Code,LeaderID=:LeaderID,MateID=:MateID, "
								+ "WorkTypeID=:WorkTypeID,FactoryID=:FactoryID, WorkshopID=:WorkshopID,DepartmentID=:DepartmentID,Description=:Description,"
								+ "EditorID = :EditorID, EditTime = now() WHERE ID = :ID;  ", wInstance);
			}

			wSQL = this.DMLChange(wSQL);
			Map<String, Object> wParamMap = new HashMap<String, Object>();

			wParamMap.put("ID", wBMSTeam.ID);
			wParamMap.put("Code", wBMSTeam.Code);
			wParamMap.put("Name", wBMSTeam.Name);
			wParamMap.put("CreatorID", wLoginUser.ID);
			wParamMap.put("EditorID", wLoginUser.ID);
			wParamMap.put("LeaderID", StringUtils.Join(",", wBMSTeam.LeaderID));
			wParamMap.put("MateID", StringUtils.Join(",", wBMSTeam.MateID));
			wParamMap.put("WorkTypeID", wBMSTeam.WorkTypeID);
			wParamMap.put("FactoryID", wBMSTeam.FactoryID);
			wParamMap.put("WorkshopID", wBMSTeam.WorkshopID);
			wParamMap.put("DepartmentID", wBMSTeam.DepartmentID);
			wParamMap.put("Active", wBMSTeam.Active);
			wParamMap.put("Description", wBMSTeam.Description);

			if (wBMSTeam.ID <= 0) {

				wBMSTeam.ID = super.insert(wSQL, wParamMap);

			} else {
				super.update(wSQL, wParamMap);
			}
		} catch (Exception e) {
			logger.error("BMS_UpdateTeam", e);
			wErrorCode.set(ExceptionTypes.DBSQL.getValue());
		}

	}

	public int BMS_DeleteTeam(BMSEmployee wLoginUser, BMSTeam wBMSTeam, OutResult<Integer> wErrorCode) {
		int wResult = 0;
		try {
			wErrorCode.set(0);
			String wInstance = super.getDBName();
			if (wErrorCode.Result != 0)
				return wResult;

			String wSQL = StringUtils.Format("Delete from {0}.bms_team  WHERE ID = :ID and Active=0;  ", wInstance);

			wSQL = this.DMLChange(wSQL);
			Map<String, Object> wParamMap = new HashMap<String, Object>();

			wParamMap.put("ID", wBMSTeam.ID);
			int wRow = super.update(wSQL, wParamMap);

			if (wRow > 0) {
				wSQL = StringUtils.Format("Delete from {0}.bms_teamitem  WHERE ID>0 and TeamID = :ID ;  ", wInstance);
				super.update(wSQL, wParamMap);
			}

		} catch (Exception e) {
			logger.error("BMS_DeleteTeam", e);
			wErrorCode.set(ExceptionTypes.DBSQL.getValue());
		}
		return wResult;
	}

	public int BMS_ActiveTeam(BMSEmployee wLoginUser, BMSTeam wBMSTeam, int wActive, OutResult<Integer> wErrorCode) {
		int wResult = 0;
		try {
			wErrorCode.set(0);
			String wInstance = super.getDBName();
			if (wErrorCode.Result != 0)
				return wResult;

			Map<String, Object> wParamMap = new HashMap<String, Object>();

			String wSQL = StringUtils.Format(
					"UPDATE {0}.bms_team SET EditorID = :wEditorID, EditTime =now(), Active = :wActive WHERE ID = :wID;  ",
					wInstance);
			wSQL = this.DMLChange(wSQL);
			wParamMap.clear();
			wParamMap.put("wID", wBMSTeam.ID);
			wParamMap.put("wActive", wActive);
			wParamMap.put("wEditorID", wLoginUser.ID);

			super.update(wSQL, wParamMap);

		} catch (Exception e) {
			logger.error("BMS_ActiveTeam", e);
			wErrorCode.set(ExceptionTypes.DBSQL.getValue());
		}
		return wResult;
	}

}
